\defmodule{BasicRandomStreamFactory}

Represents a basic random stream factory that can constructs new
instances of a given \class{RandomStream} implementation via the
\method{newInstance}{()} method.
The class name of the implementation to be used must be passed to
the constructor as a \texttt{String}, which must be the name of
a nullary constructor of a \class{RandomStream} object
(i.e., a constructor that has no parameters).
The streams are constructed by the factory by reflection from this
\texttt{String}. 


\bigskip\hrule

\begin{code}
\begin{hide}
/*
 * Class:        BasicRandomStreamFactory
 * Description:  basic random stream factory
 * Environment:  Java
 * Software:     SSJ 
 * Copyright (C) 2001  Pierre L'Ecuyer and Universite de Montreal
 * Organization: DIRO, Universite de Montreal
 * @author       
 * @since

 * SSJ is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License (GPL) as published by the
 * Free Software Foundation, either version 3 of the License, or
 * any later version.

 * SSJ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * A copy of the GNU General Public License is available at
   <a href="http://www.gnu.org/licenses">GPL licence site</a>.
 */
\end{hide}
package umontreal.iro.lecuyer.rng;\begin{hide}

import umontreal.iro.lecuyer.rng.RandomStream;
import umontreal.iro.lecuyer.rng.MRG32k3a;
\end{hide}

public class BasicRandomStreamFactory implements RandomStreamFactory\begin{hide} {
   private Class rsClass;
\end{hide}

   public BasicRandomStreamFactory (Class rsClass)\begin{hide} {
      checkRandomStreamClass (rsClass);
      this.rsClass = rsClass;
   }\end{hide}
\end{code}
\begin{tabb}  Constructs a new basic random stream factory with
 random stream class \texttt{rsClass}.
 The supplied class object must represent an implementation
 of \class{RandomStream} and must provide a nullary
 constructor.  For example, to construct a factory
 producing \class{MRG32k3a} random streams, this constructor
 must be called with \texttt{MRG33k3a.class}.
\end{tabb}
\begin{htmlonly}
   \param{rsClass}{the random stream class being used.}
   \exception{NullPointerException}{if \texttt{rsClass} is \texttt{null}.}
   \exception{IllegalArgumentException}{if \texttt{rsClass} does
    not represent an implementation of \class{RandomStream}, or
    does not provide a nullary constructor.}
\end{htmlonly}
\begin{code}

   public Class getRandomStreamClass()\begin{hide} {
      return rsClass;
   }\end{hide}
\end{code}
\begin{tabb}   Returns the random stream class associated with this
 object.
\end{tabb}
\begin{htmlonly}
   \return{the associated random stream class.}
\end{htmlonly}
\begin{code}

   public void setRandomStreamClass (Class rsClass)\begin{hide} {
      checkRandomStreamClass (rsClass);
      this.rsClass = rsClass;
   }\end{hide}
\end{code}
\begin{tabb}   Sets the associated random stream class to
 \texttt{rsClass}.
 The supplied class object must represent an implementation
 of \class{RandomStream} and must provide a nullary
 constructor.
\end{tabb}
\begin{htmlonly}
   \param{rsClass}{the random stream class being used.}
   \exception{NullPointerException}{if \texttt{rsClass} is \texttt{null}.}
   \exception{IllegalArgumentException}{if \texttt{rsClass} does
    not represent an implementation of \class{RandomStream}, or
    does not provide a nullary constructor.}
\end{htmlonly}
\begin{code}\begin{hide}

   private void checkRandomStreamClass (final Class rsClass) {
      if (!RandomStream.class.isAssignableFrom (rsClass))
         throw new IllegalArgumentException
            ("The random class must implement the RandomStream interface");
      try {
         rsClass.getConstructor (new Class[0]);
      }
      catch (NoSuchMethodException nme) {
         throw new IllegalArgumentException
            ("The random stream class " + rsClass.getName() + " does not have a " +
             "nullary public constructor.");
      }
   }

   public RandomStream newInstance() {
      try {
         return (RandomStream)rsClass.newInstance();
      }
      catch (IllegalAccessException iae) {
         throw new RandomStreamInstantiationException
            (this, "Cannot access constructor for random stream class " + rsClass.getName(),
             iae);
      }
      catch (InstantiationException ie) {
         throw new RandomStreamInstantiationException
            (this, "Cannot instantiate random stream class "
             + rsClass.getName(), ie);
      }
      catch (Exception e) {
         throw new RandomStreamInstantiationException
            (this, "Exception while calling the nullary constructor for random stream class "
             + rsClass.getName(), e);
      }
   }

   public String toString() {
      return "Basic random stream factory constructing streams of class " + rsClass.getName();
   }
}\end{hide}
\end{code}
